home *** CD-ROM | disk | FTP | other *** search
- Path: cs.tu-berlin.de!jutta
- From: jutta@cs.tu-berlin.de (Jutta Degener)
- Newsgroups: comp.std.c
- Subject: Re: setjmp usage question
- Date: 25 Feb 1996 12:24:24 GMT
- Organization: Technical University of Berlin, Germany
- Message-ID: <4gpkdo$jm8@news.cs.tu-berlin.de>
- References: <4gnusq$7be@senator-bedfellow.MIT.EDU>
- NNTP-Posting-Host: kugelbus.cs.tu-berlin.de
- Mime-Version: 1.0
- Content-Type: text/plain; charset=iso-8859-1
- Content-Transfer-Encoding: 8bit
-
- tada@athena.mit.edu (Michael J Zehr) writes:
- > I'm trying to determine whether a particular usage of setjmp is
- > sanctioned by the standard and I'm finding a compiler bug or whether my
- > usage is non-conforming.
-
- Your usage is non-conforming. The reason for that is not important
- to what you're asking, but I'll mention it to get it out of the way.
- The standard has restricted the ways in which setjmp() can be used:
-
- # An invocation of the "setjmp" macro shall appear only in one of
- # the following contexts:
- #
- # * The entire controlling expression of a selection of iteration
- # statement;
- #
- # * one operand of a relational or equality operator with the
- # other operand an integral constant expression, with the resulting
- # expression being the entire controlling expression of a selection
- # or iteration statement;
- #
- # * the operand of a unary ! operator with the resulting expression
- # being the entire controlling expression of a selection or iteration
- # statement; or
- #
- # * the entire expression of an expression statement (possibly cast
- # to void).
- # --- ANSI Section 4.6.1.1
-
- Your statement,
-
- > if (*error_code = setjmp(env[env_index++])) {
-
- is neither of these cases (the '=' means assignment, not equality), so the
- program's behavior is undefined.
-
- Let's imagine you had written
-
- if (setjmp(env[env_index++])) {
-
- > Should this code work correctly? In particular, can a compiler
- > increment env_index after longjmp is called?
-
- I think the code might or might not work, and the compiler is free to
- increment env_index after longjmp is called and flow control has returned
- to the setjmp statement. The standard doesn't impose any ordering on
- the act of "returning" from the longjmp invocation and on the side
- effects from the setjmp() statement---macro invocations like setjmp()
- do not imply sequence points in the way function invocations do.
-
- > [Additional question because I'm curious: what happens to
- > post-increments that are in parameters of the longjmp call?
-
- I think that unless you take special care, the same applies, but you'll
- find people to argue otherwise. (See below.)
-
- For a bit of background---
-
- The standard specifies one type of sequence point that's interesting
- for us here:
-
- # The order of evaluation of the function designator, the arguments,
- # and subexpressions within the arguments is unspecified, but there is a
- # sequence point before the actual call.
- #
- # --ANSI section 3.3.2.2, Function Calls.
-
- That this is the only place that applies is in itself significant: there
- are no special sequence points for longjmp and setjmp; they behave just
- like any old function---or macro.
-
- Setjmp, although it looks much like a function, is not described as a
- function in the standard; it is a macro. Among other things, that means
- you can't rely on a sequence point between the evaluation of setjmp's
- argument and the "call".
-
- Longjmp is described as a function in the standard. Does that mean it
- is a function? Yes and no. There is a function called longjmp, and if
- you write a call
-
- #include <setjmp.h>
- (longjmp)(env[env_index++], 1);
- or
- #include <setjmp.h>
- #undef longjmp
- longjmp(env[env_index++], 1);
- or
- #include <setjmp.h>
- void (* f)(jmp_buf, int) = longjmp;
- f(env[env_index++], 1);
-
- so that longjmp can't possibly be a macro, you are guaranteed to get
- a real function, complete with sequence point and all. In these cases,
-
- (longjmp)(env[env_index++], 1);
-
- is equivalent to
-
- env_index++; longjmp(env[env_index - 1], 1);
-
- since the side effects of the "++" operator must be complete before
- the actual function is invoked.
-
- But as long as you don't jump through any of the three hoops above
- and naively use
-
- #include <setjmp.h>
- longjmp(env[env_index++], 1);
-
- what you actually get may or may not be a call to the "real" longjmp
- function, because
-
- # Any function declared in a header may be additionally
- # implemented as a macro
- #
- # -- ANSI Section 4.1.6, Use of Library Functions
-
- Whether this means that
-
- (a) users cannot rely on the sequence point between argument evaluation
- and call unless they make sure they're using a "real" function
-
- or whether this means that
-
- (b) implementors who implement Standard C functions as macros must
- guarantee that function-call like sequence points apply even in
- the macro expansions
-
- hasn't been formally decided within WG14 yet, as far as I remember.
-
- Jutta Degener (jutta@cs.tu-berlin.de), speaking only for myself.
-